package com.sali.b_design_pattern.l_prototype_pattern;

import com.sali.b_design_pattern.l_prototype_pattern.entity.Addresss;
import com.sali.b_design_pattern.l_prototype_pattern.entity.Addresss2;
import com.sali.b_design_pattern.l_prototype_pattern.entity.PrototypeVersion1;
import com.sali.b_design_pattern.l_prototype_pattern.entity.PrototypeVersion2;

/**
 * @description:
 * @author: zhang hang
 * @date: 2023/3/18 21:33.
 * @version: 1.0
 */
public class Client {

    public static void main(String[] args) throws CloneNotSupportedException {
        // 浅拷贝
//        prototypeVersion1();

        // 深拷贝
        prototypeVersion2();

//        ArrayList<Integer> arrayList1 = new ArrayList<>();
//        arrayList1.add(1);
//        arrayList1.add(2);
//        arrayList1.add(3);
//        ArrayList<Integer> arrayList2 = (ArrayList<Integer>) arrayList1.clone();
//        arrayList2.add(4);
//        // 3
//        System.out.println(arrayList1.size());
//        // 4
//        System.out.println(arrayList2.size());
    }


    private static void prototypeVersion1() throws CloneNotSupportedException {
        // 本地对象
        PrototypeVersion1 p1 = new PrototypeVersion1();
        p1.setName("小A");
        p1.setAddresss(new Addresss("广东", "广州"));

        // 复制
        PrototypeVersion1 p2 = (PrototypeVersion1) p1.clone();
        p2.setName("小B");
        p2.getAddresss().setCity("江门");


        // 得出结论：默认一个原型对象中如果包含了类类型的引用，那么默认是浅拷贝。最后更改的都是同一个内存空间地址
        // 那么为什么Prototype对象更改了？因为它实现了Cloneable借口覆盖clone方法。所以它们两个p1和p2是两个内存空间地址
        // 但对于内部的引用对象如果没有实现Cloneable接口覆盖clone方法默认都是一个内存空间地址（浅拷贝）
        System.out.println("p1--" + p1.getName() + "--" + p1.getAddresss().getCity()); // p1--小A--江门
        System.out.println("p2--" + p2.getName() + "--" + p2.getAddresss().getCity()); // p2--小B--江门
    }

    private static void prototypeVersion2() throws CloneNotSupportedException {
        // 本地对象
        PrototypeVersion2 pnew1 = new PrototypeVersion2();
        pnew1.setName("小A");
        pnew1.setAddresss2(new Addresss2("广东", "广州"));

        // 复制
        PrototypeVersion2 pnew2 = (PrototypeVersion2) pnew1.clone();
        pnew2.setName("小B");
        pnew2.getAddresss2().setCity("江门");

        // 这里是深拷贝了
        System.out.println("pnew1--" + pnew1.getName() + "--" + pnew1.getAddresss2().getCity()); // pnew1--小A--广东
        System.out.println("pnew2--" + pnew2.getName() + "--" + pnew2.getAddresss2().getCity()); // pnew2--小B--江门
    }

}
